home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: CDragDropTableTask.c
- * Created: 8/1/93
- * Desc: A mousetask that handles dragging and dropping
- * in CItemTable.
- *
- * Superclass: CTableDragger.
- * Uses: CItemTable, CItem.
- * Original Author: W. Wesley Monroe
- * Modifications:
- *
- * Copyright © 1993 Animas Software Production. All rights reserved.
- */
-
- #include "CDragDropTableTask.h"
- #include "CItemTable.h"
- #include "CItemList.h"
- #include "LongQD.h"
- #include "CItem.h"
-
- extern CBureaucrat *gGopher;
-
- void CDragDropTableTask::IDragDropTableTask(CTable *aTable,
- CView *dragBoundsPane,
- short theModifiers,
- long selFlags)
- {
- ITableDragger(aTable, theModifiers, selFlags);
-
- fCanDragDrop = (selCanDrag & selFlags) | (selCanRecieve & selFlags);
-
- fEnclosingPano = dragBoundsPane;
- fDropTarget = FALSE;
- fGRDrawn = FALSE;
- fFirst = TRUE;
- fGrayRgn = 0;
- fReleasedView = fOriginalView = aTable;
-
- fSelectedItems = 0L;
- }
-
- void CDragDropTableTask::Dispose(void)
- {
- ForgetObject(fSelectedItems);
-
- inherited::Dispose();
- }
-
- void CDragDropTableTask::BeginTracking(LongPt *startPt)
- {
- Cell hitCell;
- RgnHandle aRgn;
-
- itsTable->FindHitCell(startPt, &hitCell);
-
- fDropTargetCell = hitCell;
- // Call Begin Tracking only if modifierkeys are down,
- // or the hitCell is not Selected.....
- if(modifierKeys || !itsTable->IsSelected(hitCell))
- inherited::BeginTracking(startPt);
-
- fSelectedItems = ((CItemTable *) itsTable)->GetHiliteRgn(&aRgn);
- fGrayRgn = aRgn;
- }
-
- void CDragDropTableTask::KeepTracking(LongPt *currPt, LongPt *prevPt,
- LongPt *startPt)
- {
- CView *theDropInView;
- CView *enclView = fEnclosingPano;
- CItemTable *dropInTable;
-
- PenState saveState;
- RgnHandle aRgn = fGrayRgn;
- Point scp;
- Cell hitCell;
- Rect r, r2;
- Point cp;
-
- GetPenState(&saveState);
-
- if(fFirst && !EqualLongPt(currPt, prevPt)) {
- PenPat(gray);
- PenMode(srcXor);
- FrameRgn(aRgn);
- fFirst = FALSE;
- fGRDrawn = TRUE;
- } else if(!EqualLongPt(currPt, prevPt)) {
- PenPat(gray);
- PenMode(srcXor);
- FrameRgn(aRgn);
- OffsetRgn(aRgn, (short) (currPt->h - prevPt->h),
- (short) (currPt->v - prevPt->v));
- FrameRgn(aRgn);
- fGRDrawn = TRUE;
- fFirst = FALSE;
-
- ASSERT(fEnclosingPano);
-
- scp.h = currPt->h - enclView->macPort->portRect.left;
- scp.v = currPt->v - enclView->macPort->portRect.top;
-
- // ((CPane*)fEnclosingPano)->FrameToWind(currPt, &scp);
- theDropInView = enclView->FindSubview(scp);
-
- if(theDropInView) {
-
- // For now, the only panes that can recieve are ScrollPanes
- // with ItemTables en em...
- if(member(theDropInView, CScrollPane)) {
- dropInTable = (CItemTable *)
- ((CScrollPane *) theDropInView)->itsPanorama;
- } else if(member(theDropInView, CItemTable))
- dropInTable = (CItemTable *) theDropInView;
- else
- return;
-
- if(dropInTable && dropInTable->GetCanRecieve()) {
- LongPt p;
-
- fReleasedView = dropInTable;
- // Make the table the gopher...
- if(gGopher != dropInTable)
- dropInTable->BecomeGopher(TRUE);
-
- if(dropInTable != fOriginalView) {
-
- dropInTable->WindToFrame(scp, &p);
- dropInTable->FindHitCell(&p, &hitCell);
-
- } else
- dropInTable->FindHitCell(currPt, &hitCell);
-
- r.top = hitCell.v; r.left = hitCell.h;
- r.bottom = r.top + 1;
- r.right = r.left + 1;
- if((dropInTable != fOriginalView) || !PtInRect(fDropTargetCell, &r)) {
-
- // Only deselect if it was already selected
- if(fDropTarget) {
- fDropTarget = FALSE;
- r2.top = fDropTargetCell.v;
- r2.left = fDropTargetCell.h;
- r2.bottom = r2.top + 1;
- r2.right = r2.left + 1;
- dropInTable->Hilite(&r2, FALSE);
- }
-
- if(!dropInTable->HitInDrag(hitCell)
- && dropInTable->ItemCanAcceptDrop(hitCell, fSelectedItems)) {
- // Hilite the new one
- dropInTable->Hilite(&r, TRUE);
- fDropTarget = TRUE;
- }
- fDropTargetCell = hitCell;
- }
- }
- }
- }
-
- itsTable->AutoScroll( currPt);
- fGrayRgn = aRgn;
- SetPenState(&saveState);
- }
-
- void CDragDropTableTask::EndTracking(LongPt *currPt, LongPt *prevPt,
- LongPt *startPt)
- {
- CItemList *selList;
-
- Cell dropCell = {0, 0};
- Cell hitCell;
- PenState saveState;
- RgnHandle aRgn = fGrayRgn;
-
- // Erase the last gray region...
- if(fGRDrawn) {
-
- GetPenState(&saveState);
-
- PenPat(gray);
- PenMode(srcXor);
- OffsetRgn(aRgn, (short) (currPt->h - prevPt->h),
- (short) (currPt->v - prevPt->v));
- FrameRgn(aRgn);
-
- SetPenState(&saveState);
- }
- // Region be gone...
- DisposeRgn(aRgn);
- fGrayRgn = 0L;
-
- ASSERT(fReleasedView);
-
- selList = fSelectedItems;
-
- /*
- * See if items were dropped in a ItemTable or one of its
- * subclasses.
- */
-
- if(member(fReleasedView, CItemTable)) {
-
- CItem *firstSelItem, *dropTargetItem;
- CItemList *copy;
- CItemTable *targetList = (CItemTable *) fReleasedView;
- CItemTable *originalList = (CItemTable *) fOriginalView;
-
- targetList->FindHitCell(startPt, &hitCell);
-
- // Which cell was the item dropped in...
- targetList->FindHitCell(currPt, &dropCell);
-
-
- if(dropCell.v >= 0)
- dropTargetItem = targetList->GetItem(dropCell.v + 1);
- else
- dropTargetItem = 0L;
-
- /*
- * If they clicked and released in the same cell, and
- * that cell is not a root object, and the option key
- * is down, move the item to the top of the tree.
- */
-
- if(hitCell.v == dropCell.v) {
- if(modifierKeys & optionKey && dropTargetItem->GetLevel() != 0) {
-
- // Remove an item to the top of the hierarchy...
- targetList->RemoveSubviews(selList);
-
- targetList->GraftItems(0L, selList);
- }
- return;
- }
-
- firstSelItem = (CItem *) selList->FirstItem();
-
- /*
- * If they did not drop in the same cell or
- * they dropped in a different view, remove the items
- * from the original list and graft them under the
- * target item.
- */
-
- /* if((hitCell.v + 1 != dropCell.v || t != t2 ) &&*/
- /* !t2->DropedSameParent(dropCell.v,*/
- /* firstSelItem)) {*/
- /* if(hitCell.v + 1 != dropCell.v ||*/
- /* targetList != originalList) {*/
-
- if(dropCell.v <= 0 || targetList->ItemCanAcceptDrop(dropCell, selList)) {
-
- originalList->RemoveSubviews(selList);
- targetList->GraftItems(dropTargetItem, selList);
- }
- }
- }
-